<?php
declare(strict_types=1);

namespace App\Resource\Service\Goods;


use App\Common\Service\BaseService;
use App\Resource\Repository\RepositoryFactory;
use App\Resource\Service\BuildGoodsService;

class GoodsBaseService extends BaseService
{
    /**
     * 公共字段集合
     */
    const GOODSFIELD=['id','title','goods_crm_code','read_pos_price','read_pos_stock','scant_id','status','ratio','safety_stock','logo','image','group_id','content','share_image','introduction','mini_app_code','kz_goods_id','shop_ids','crd_shop_ids','sort'];
    const GOODSLISTFIELD=['goods_spec','price_selling', 'price_market', 'number_stock','number_virtual', 'number_sales','goods_pick_time','limite_num_per_day'];
    const SCHEMEFIELD=['schemeID'];
    const SCHEMEGOODSFIELD=['crm_goods_id','price','stdPrice'];

    const GOODS_ARCHIVES_REDIS_KEY = 'Goods:GoodsArchivesMsg:';
    const GOODS_OVER_NIGHT_ARCHIVES_REDIS_KEY = 'Goods:GoodsOverNightArchivesMsg:';

    const GOODS_EXPIRE = 10;

    const GOODS_VALET_CATR ='shop-cart';

    const GOODS_VALET_TIMELY_CART =1;

    const GOODS_VALET_OVERNIGHT_CART =2;
    /**
     * 及时达商城
     */
    const TIMELY_ARRIVE_SHOP_TYPE = 'timely';
    /**
     * 次日达商城
     */
    const OVERNIGHT_ARRIVE_SHOP_TYPE = 'tomorrow';

    /**
     * 及时达商品
     */
    const TIMELY_ARRIVE_GOODS = '1';
    /**
     * 次日达商品
     */
    const OVERNIGHT_ARRIVE_GOODS = '1';
    /**
     *  0、普通商品 1、小跑好物拼团  2、会员专区 3、限时抢购
     */
    const GOODS_GROUP_0 =0;
    const GOODS_GROUP_1 =1;
    const GOODS_GROUP_2 =2;
    const GOODS_GROUP_3 =3;
    /**
     * 首页展示 0：关闭 1：开启
     */
    const GOODS_IS_HOME_0 = 0;
    const GOODS_IS_HOME_1 = 1;
    /**
     * 热销状态 0：关闭 1：开启
     */
    const GOODS_IS_HOT_0 = 0;
    const GOODS_IS_HOT_1 = 1;
    /**
     * 商品状态 0禁用，1启用
     */
    const GOODS_STATUS_0 = 0;
    const GOODS_STATUS_1 = 1;
    /**
     * 删除状态 0未删除，1已删除
     */
    const GOODS_IS_DELETED_0 = 0;
    const GOODS_IS_DELETED_1 = 1;
    /**
     * 商品种类 0、标品  1、非标品
     */
    const GOODS_SCANT_0 = 0;
    const GOODS_SCANT_1 = 1;
    /**
     * 是否读库存0读1不读
     */
    const STOCK_TYPE_0 = 0;
    const STOCK_TYPE_1 = 1;
    /**
     * 库存状态 0不读，1读取
     */
    const GOODS_READ_POS_STOCK_0 = 0;
    const GOODS_READ_POS_STOCK_1 = 1;

    /**
     * 读取POS价格状态 0不读，1读取
     */
    const GOODS_READ_POS_PRICE_0 = 0;
    const GOODS_READ_POS_PRICE_1 = 1;

    /**
     * Repository
     */
    protected $goods;
    protected $shop;
    protected $lsyPrice;
    /**
     * GoodsMiniService constructor.
     * @param RepositoryFactory $repoFactory
     */
    public function __construct(RepositoryFactory $repoFactory)
    {
        parent::__construct();
        $this->goods = $repoFactory->getRepository("goods");
        $this->shop = $repoFactory->getRepository("shop");
        $this->lsyPrice = $repoFactory->getRepository("lsyPrice");
    }

    /**
     * 商品档案列表公共服务（功能适用多端）业务场景（及时达）
     * @param array $needExceptKey
     * @param int $shop_id
     * @param int $page
     * @param int $limit
     * @return array
     * @author ran
     * @date 2021-02-24 13:46
     * mailbox 466180170@qq.com
     */
    public  function getResourceCommonTimelyArriveGoodsList(array $needExceptKey=[],int $shop_id,int $page=1,int $limit=20,array $extraCondition=[],bool $isPage=true,array $orderBy=[]): array
    {
        $lsyShopNo =$this->shop->findFirstValue('lsy_shop_no',['shop_id'=>$shop_id]);
        $where =['store_goods.is_today'=>self::TIMELY_ARRIVE_GOODS,'store_goods.is_deleted'=>self::GOODS_IS_DELETED_0];
        $unionWhere=['createShopId'=>$lsyShopNo];
        $condition=['where'=>array_merge($where,$extraCondition['where']??[]),'whereRaw'=>$extraCondition['whereRaw']??[],'whereNotIn'=>$extraCondition['whereNotIn']??[],'whereIn'=>$extraCondition['whereIn']??[],'whereOp'=>$extraCondition['whereOp']??[],'unionWhere'=>$unionWhere];
        $goodsTimelyArrivesArray= $this->goods->selectMoreUnionList(self::GOODSFIELD,self::GOODSLISTFIELD,$condition,$page,$limit,$orderBy,$isPage);
        $schemePrice=$this->lsyPrice->selectUnionListNoPage(self::SCHEMEFIELD,self::SCHEMEGOODSFIELD,$lsyShopNo);
        $schemePriceArr = collect($schemePrice)->keyBy('crm_goods_id')->toArray();
        $goodsTimelyArrivesArray['list'] =$this->getCommonChangeGoodsPriceOrStock($goodsTimelyArrivesArray['list'],$schemePriceArr,$lsyShopNo);
        $goodsTimelyArrivesArray['list'] =$this->arr->arraySort($goodsTimelyArrivesArray['list'],'number_stock');
        $goodsTimelyArrivesArray['list']=$this->arr->exceptMoreArrKey($goodsTimelyArrivesArray['list'],$needExceptKey);
        return $goodsTimelyArrivesArray;
    }
    /**
     * 商品档案详情公共服务（功能适用平台多端）业务场景（及时达）
     * @param int $id 主表主键
     * @param int $shop_id 店铺ID
     * @param array|string[] $field  主表字段集合
     * @param array|string[] $sonField 子表字段集合
     * @param array $needExceptKey 需要剔除的键
     * @return array
     * @author zhangzhiyuan
     */
    public  function getResourceCommonTimelyArriveGoodsMsg(int $id, int $shop_id,array $needExceptKey=[]): array
    {
        $goodsMsgData= $this->goods->getResourceSingleSonByPrimaryId($id,self::GOODSFIELD,self::GOODSLISTFIELD);
        $lsyShopNo =$this->shop->findFirstValue('lsy_shop_no',['shop_id'=>$shop_id]);
        $shopGoodsPriceByScheme=$this->lsyPrice->getThirdSingleSonByPrimaryId($goodsMsgData['goods_crm_code'],$lsyShopNo,self::SCHEMEFIELD,self::SCHEMEGOODSFIELD);
        $schemePriceArr = collect([$shopGoodsPriceByScheme])->keyBy('crm_goods_id')->toArray();
        $GoodsArchivesArr=array_reduce($this->getCommonChangeGoodsPriceOrStock([$goodsMsgData],$schemePriceArr,$lsyShopNo), 'array_merge', array());
        return $this->arr->exceptArrKey($GoodsArchivesArr,$needExceptKey);
    }
    /**
     * 商品档案详情公共服务（功能适用平台多端）业务场景（次日达）
     * @param int $id 主表主键
     * @param array|string[] $field  主表字段集合
     * @param array|string[] $sonField 子表字段集合
     * @param array $needExceptKey 需要剔除的键
     * @return array
     * @author zhangzhiyuan
     */
    public function getResourceCommonOverNightArriveGoodsMsg(int $id,array $needExceptKey=[]): array
    {
        $goodsMsgData= $this->goods->getResourceSingleSonByPrimaryId($id,self::GOODSFIELD,self::GOODSLISTFIELD);
        return $this->arr->exceptArrKey($goodsMsgData,$needExceptKey);
    }

    /**
     * 次日达商品集合公共服务（功能适用平台多端）业务场景（次日达）
     * @param array $needExceptKey
     * @param array $where
     * @param $whereRaw
     * @param array $whereIn
     * @param array $whereNotIn
     * @param int $page
     * @param int $limit
     * @param array|string[] $orderBy
     * @return array
     * @author zhangzhiyuan
     */
    public function getResourceCommonOverNightArriveGoodsList(array $needExceptKey=[],int $page,int $limit,array $extraCondition=[],array $orderBy=[]): array
    {
        $where =['store_goods.is_next_day'=>self::OVERNIGHT_ARRIVE_GOODS,'store_goods.is_deleted'=>self::GOODS_IS_DELETED_0];
        $whereOp =[['store_goods_list.number_stock','>',0]];
        $condition=['where'=>array_merge($where,$extraCondition['where']??[]),'whereRaw'=>$extraCondition['whereRaw']??[],'whereNotIn'=>$extraCondition['whereNotIn']??[],'whereOp'=>array_merge($whereOp,$extraCondition['whereOp']??[])];
        $GoodsOverNightArrivesArray= $this->goods->selectUnionList(self::GOODSFIELD,self::GOODSLISTFIELD,$condition,$page,$limit,$orderBy);
        $GoodsOverNightArrivesArray['list']=$this->arr->exceptMoreArrKey($GoodsOverNightArrivesArray['list'],$needExceptKey);
        return $GoodsOverNightArrivesArray;
    }

    /**
     * （功能适用平台多端）业务场景（及时达首页精选产品、次日达首页商品列表）
     * @param string $type
     * @param int $shop_id
     * @param $limit
     * @param $page
     * @return array
     * @author ran
     * @date 2021-03-02 15:04
     * mailbox 466180170@qq.com
     */
    public function getResourceCommonGoodsListForShopByRedis(string $shopType, int $shop_id, $limit, $page){
        $redis = $this->buildRedis;
        if ($shopType == 'timely'){
            $key0 = "timely:goods";
            $key1 = "timely:shop:{$shop_id}:goods";
            $key2 = "timely:shop:{$shop_id}:goods:sort";
            if ($redis->hLen($key0) == 0) $this->container->get(BuildGoodsService::class)->buildGoodsListToRedis('timely');
        }else{
            $key0 = "tomorrow:goods";
            $key1 = "tomorrow:shop:{$shop_id}:goods";
            $key2 = "tomorrow:shop:{$shop_id}:goods:sort";
        }
        $count = $redis->zCard($key2);
        $ret = $redis->zRange($key2, $limit * $page - $limit, $limit * $page - 1);
        if ($count > 0 && count($ret) > 0){
            $commList = $redis->hMGet($key0, $ret);
            $list = $redis->hMGet($key1, $ret);
            foreach ($commList as $goods_id => &$item){
                $item = array_merge(json_decode($item, true), json_decode($list[$goods_id],true));
            }
            return ['count' => $count,'list' => array_values($commList)];
        }else{
            return ['count' => 0,'list' => []];
        }
    }

    /**
     * 组装redis数据公共服务
     * @param int $id
     * @param array $needExceptKey
     * @return array
     * @author ran
     * @date 2021-03-02 15:51
     * mailbox 466180170@qq.com
     */
    public function getResourceCommonTimelyArriveExceptGoodsListKeyByRedis(array $redisArray,array $needExceptKey=[]): array
    {
        $redisGoodsArray= $this->arr->exceptMoreArrKey($redisArray,$needExceptKey);
        foreach ($redisGoodsArray as $k=>$goods){
            $redisGoodsArray[$k]['number_sales'] = $goods['number_sales'] + $goods['number_virtual'];
            $redisGoodsArray[$k]['number_stock'] = (int)$goods['surplusQuantity'];
            unset($redisGoodsArray[$k]['surplusQuantity']);
        }
        return $redisGoodsArray;
    }

    /**
     * 及时达获取商品价格的服务
     * @param array $needExceptKey
     * @param int $shop_id
     * @param array $goods
     * @return array
     * @author ran
     * @date 2021-03-16 16:09
     * mailbox 466180170@qq.com
     */
    public  function getResourceCommonChangeGoodsPrice(array $needExceptKey=[],int $shop_id,array $goods): array
    {
        $lsyShopNo =$this->shop->findFirstValue('lsy_shop_no',['shop_id'=>$shop_id]);
        $schemePrice=$this->lsyPrice->selectUnionListNoPage(self::SCHEMEFIELD,self::SCHEMEGOODSFIELD,$lsyShopNo);
        $schemePriceArr = collect($schemePrice)->keyBy('crm_goods_id')->toArray();
        array_walk($goods, function(&$item) use ($schemePriceArr){
            if ($item['read_pos_price'] == self::GOODS_READ_POS_PRICE_1){
                $posSellingPrice = array_key_exists($item['goods_crm_code'], $schemePriceArr) ? $schemePriceArr[$item['goods_crm_code']]['price'] : $item['price_selling'];
            }else{
                $posSellingPrice = $item['price_selling'];
            }
            $item['price_selling'] = $item['scant_id'] == self::GOODS_SCANT_1 ? bcmul(bcdiv($posSellingPrice,'1000',6),(string)$item['ratio'],2) : $posSellingPrice;
        });
        $goods=$this->arr->exceptMoreArrKey($goods,$needExceptKey);
        return $goods;
    }

}